#include "qproject.h"

#include "rcc.h"
#include "qabstractdrive.h"
#include "qdriveplugininterface.h"
#include "qdriveattribute.h"

#include <QResource>
#include <QFile>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QMessageBox>
#include <QDir>

QProject* QProject::m_project=NULL;

QProject::QProject() :
    QObject(0),
    m_durty(true)
{
}

QProject::~QProject()
{
    close();
}

bool QProject::open(const QString &path)
{
    close();

    QString p=path;
    p.replace("\\","/");
    int index=p.lastIndexOf("/");
    m_projectPath=p.left(index);
    m_projectFileName=p.mid(index+1);

    QFile f(path);

    if(!f.open(QFile::ReadOnly))
    {
        return false;
    }
    QByteArray array=f.readAll();
    QString str=QString::fromLocal8Bit(array.data());
    QXmlStreamReader r(str);

    while(!r.atEnd())
    {
        if(r.readNext()==QXmlStreamReader::StartElement)
        {
            readProject(&r);
        }
    }
    f.close();
    if(r.hasError())
    {
        close();
        return false;
    }
    emit openProject();
    setDurty(false);
    return true;
}

int QProject::readInt(QByteArray &array)
{
    int ret=0;
    ret+=((array.at(0)&0xff)<<24);
    array=array.mid(1);
    ret+=((array.at(0)&0xff)<<16);
    array=array.mid(1);
    ret+=((array.at(0)&0xff)<<8);
    array=array.mid(1);
    ret+=((array.at(0)&0xff));
    array=array.mid(1);
    return ret;
}

void QProject::readProject(QXmlStreamReader *r)
{
    foreach(const QXmlStreamAttribute &attribute,r->attributes())
    {
        QStringRef name=attribute.name();
        if(name==QLatin1String("project_name"))
        {
            m_projectInfo.m_projectName=attribute.value().toString();
        }
        else if(name==QLatin1String("project_notes"))
        {
            m_projectInfo.m_projectNotes=attribute.value().toString();
        }
        else if(name==QLatin1String("first_page"))
        {
            m_projectInfo.m_strFirstPage=attribute.value().toString();
        }
    }
    for(bool finished=false;!finished && !r->hasError();)
    {
        switch(r->readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString tag=r->name().toString().toLower();
            if(tag==QLatin1String("page"))
            {
                readPage(r);
            }
            else if(tag==QLatin1String("design_size"))
            {
                m_projectInfo.m_designSize=readSize(r);
            }
            else if(tag==QLatin1String("running_size"))
            {
                m_projectInfo.m_runningSize=readSize(r);
            }
            else if(tag==QLatin1String("runtimedata"))
            {

                readRuntime(r);
            }
            else if(tag==QLatin1String("drive"))
            {
                readDrive(r);
            }
        }
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        default:
            break;
        }
    }
}

QSize QProject::readSize(QXmlStreamReader *r)
{
    QSize ret;
    foreach(const QXmlStreamAttribute &attribute,r->attributes())
    {
        QStringRef name=attribute.name();
        if(name==QLatin1String("width"))
        {
            ret.setWidth(attribute.value().toString().toInt());
        }
        else if(name==QLatin1String("height"))
        {
            ret.setHeight(attribute.value().toString().toInt());
        }
    }
    for(bool finished=false;!finished && !r->hasError();)
    {
        switch(r->readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        default:
            break;
        }
    }
    return ret;
}

void QProject::readPage(QXmlStreamReader *r)
{
    QString type="page";
    QString name;
    foreach(const QXmlStreamAttribute &attribute,r->attributes())
    {
        QStringRef name=attribute.name();
        if(name==QLatin1String("type"))
        {
            type=attribute.value().toString();
        }
    }
    for(bool finished=false;!finished && !r->hasError();)
    {
        switch(r->readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            name=r->text().toString();
        default:
            break;
        }
    }
    if(name!="")
    {
        QFile f(m_projectPath+"/page/"+name+".ui");
        if(f.open(QFile::ReadOnly))
        {
            tagPageInfo *info;
            info=new tagPageInfo;
            QByteArray array=f.readAll();
            info->m_data=QString::fromLocal8Bit(array.data());
            info->m_name=name;
            info->m_type=type;
            m_projectInfo.m_pageList.append(info);
        }
    }
}

void QProject::readRuntime(QXmlStreamReader *r)
{
    QRuntimeData *info;
    info=new QRuntimeData();
    info->read(*r);
    m_projectInfo.m_runtimeDataList.append(info);
}

void QProject::readDrive(QXmlStreamReader *r)
{
    tagDriveInfo *info;
    QString name;
    QString path;
    foreach(const QXmlStreamAttribute &attribute,r->attributes())
    {
        QStringRef n=attribute.name();
        if(n==QLatin1String("name"))
        {
            name=attribute.value().toString();
        }
        else if(n==QLatin1String("path"))
        {
            path=attribute.value().toString();
        }

    }
    for(bool finished=false;!finished && !r->hasError();)
    {
        switch(r->readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            name=r->text().toString();
        default:
            break;
        }
    }
    if(name!="" && path!="")
    {
        info=new tagDriveInfo;
        info->m_name=name;
        info->m_path=path;
        tagDrivePluginInfo in=m_drives.value(info->m_path.split(":").first());
        if(in.m_path!="")
        {
            info->m_drive=in.m_drivePlugin->createDrive(info->m_path.split(":").at(1));
            if(info->m_drive!=NULL)
            {
                QDriveAttribute *attr=info->m_drive->attribute("Name");
                attr->setValue(info->m_name);
                info->m_drive->readConfig();
                info->m_drive->readValue();
                m_projectInfo.m_drives.append(info);
                connect(info->m_drive,SIGNAL(attributeChanged()),this,SLOT(driveAttributeChanged()));
                connect(info->m_drive,SIGNAL(valueChanged()),this,SLOT(driveAttributeChanged()));
            }
        }
    }
}

bool QProject::save()
{
    return save(m_projectPath+"/"+m_projectFileName);
}

bool QProject::save(const QString &path)
{

    QFile f(path);

    if(!f.open(QFile::WriteOnly))
    {
        return false;
    }
    f.resize(0);

    QXmlStreamWriter w(&f);

    w.setAutoFormatting(true);

    w.writeStartDocument();

    w.writeStartElement("","project");


    w.writeAttribute("project_name",m_projectInfo.m_projectName);
    w.writeAttribute("project_notes",m_projectInfo.m_projectNotes);
    w.writeAttribute("first_page",m_projectInfo.m_strFirstPage);

    w.writeStartElement("design_size");
    w.writeAttribute("width",QString::number(m_projectInfo.m_designSize.width()));
    w.writeAttribute("height",QString::number(m_projectInfo.m_designSize.height()));
    w.writeEndElement();

    w.writeStartElement("running_size");
    w.writeAttribute("width",QString::number(m_projectInfo.m_runningSize.width()));
    w.writeAttribute("height",QString::number(m_projectInfo.m_runningSize.height()));
    w.writeEndElement();

    QRuntimeData *info;
    for(int i=0;i<m_projectInfo.m_runtimeDataList.size();i++)
    {
        info=m_projectInfo.m_runtimeDataList.at(i);
        info->write(w);
    }

    foreach(tagDriveInfo *in,m_projectInfo.m_drives)
    {
        w.writeStartElement("drive");
        w.writeAttribute("name",in->m_name);
        w.writeAttribute("path",in->m_path);
        w.writeEndElement();
        in->m_drive->saveConfig();
        in->m_drive->saveValue();
    }

    QDir dir(m_projectPath+"/page/");
    if(!dir.exists())
    {
        dir.mkdir(m_projectPath+"/page/");
    }
    foreach(tagPageInfo* info,m_projectInfo.m_pageList)
    {
        w.writeStartElement("page");
        w.writeAttribute("type",info->m_type);
        w.writeCharacters(info->m_name);
        w.writeEndElement();
        QFile f(m_projectPath+"/page/"+info->m_name+".ui");
        if(f.open(QFile::WriteOnly))
        {

            f.resize(0);
            f.write(info->m_data.toLocal8Bit());
            f.close();
        }
    }

    QFile ff(m_projectPath+"/project.res");

    if(ff.open(QFile::WriteOnly))
    {
        ff.resize(0);
        QByteArray buff;
        buff.append("qres");
        writeInt(buff,m_projectInfo.m_resourceList.size());
        foreach(tagResourctInfo *info,m_projectInfo.m_resourceList)
        {
             writeInt(buff,info->m_data.size());
             writeInt(buff,info->m_name.size());
             buff.append(info->m_name);
             buff.append(info->m_data);
        }
        ff.write(buff);
        ff.close();
    }


    w.writeEndElement();


    w.writeEndDocument();

    f.close();
    setDurty(false);
    emit saveProject();
    return true;
}

void QProject::writeInt(QByteArray &array, int value)
{
    array.append((value>>24)&0xff);
    array.append((value>>16)&0xff);
    array.append((value>>8)&0xff);
    array.append((value)&0xff);
}

bool QProject::close()
{
    emit beforeClosed();

    m_projectInfo.m_projectName=m_projectInfo.m_strFirstPage=m_projectInfo.m_projectNotes="";
    m_projectInfo.m_designSize=m_projectInfo.m_runningSize=QSize();
    m_projectPath=m_projectFileName="";
    qDeleteAll(m_projectInfo.m_runtimeDataList);
    m_projectInfo.m_runtimeDataList.clear();
    qDeleteAll(m_projectInfo.m_resourceList);
    m_projectInfo.m_resourceList.clear();
    qDeleteAll(m_projectInfo.m_pageList);
    m_projectInfo.m_pageList.clear();
    qDeleteAll(m_projectInfo.m_drives);
    m_projectInfo.m_drives.clear();
    m_projectInfo.m_couldMax=m_projectInfo.m_needFrame=m_projectInfo.m_couldMin=true;
    m_projectInfo.m_backgroundColor=QColor(0,0,0);
    QMapIterator<QString,uchar*>    it(m_resourceData);
    while(it.hasNext())
    {
        it.next();
        QResource::unregisterResource(it.value(),"/soft_res/");
        delete [] it.value();
    }
    m_resourceData.clear();

    QMapIterator<QString,uchar*>    i(m_tempResource);
    while(i.hasNext())
    {
        i.next();
        QResource::unregisterResource(i.value(),"/soft_res/");
        delete [] i.value();
    }
    m_tempResource.clear();
    m_resourceUser.clear();
    return true;
}

void QProject::newProject(const QString &path, const QString &name)
{
    close();
    m_projectPath=path;
    m_projectFileName="config.pro";
    m_projectInfo.m_projectName=name;
    m_projectInfo.m_designSize=m_projectInfo.m_runningSize=QSize(800,600);
    m_projectInfo.m_strFirstPage="main";

    tagPageInfo info;
    info.m_name="main";
    insertPage(-1,info);

    save();
    close();
    open(path+"/config.pro");
    emit newProject();
}

void QProject::setProjectName(const QString &name)
{
    if(m_projectInfo.m_projectName!="" && m_projectInfo.m_projectName!=name)
    {
        m_projectInfo.m_projectName=name;
        emit changed(PCT_NAME);
        setDurty(true);
    }
}

QString QProject::getProjectName()
{
    return m_projectInfo.m_projectName;
}

void QProject::setProjectNotes(const QString &notes)
{
    if(m_projectInfo.m_projectNotes!=notes)
    {
        m_projectInfo.m_projectNotes=notes;
        emit changed(PCT_NOTES);
        setDurty(true);
    }
}

QString QProject::getProjectNotes()
{
    return m_projectInfo.m_projectNotes;
}

void QProject::setFirstPage(const QString &page)
{
    if(m_projectInfo.m_strFirstPage!=page)
    {
        m_projectInfo.m_strFirstPage=page;
        emit changed(PCT_FIRST_PAGE);
        setDurty(true);
    }
}

QString QProject::getFirstPage()
{
    return m_projectInfo.m_strFirstPage;
}

void QProject::setDesignSize(const QSize &size)
{
    if(m_projectInfo.m_designSize!=size)
    {
        m_projectInfo.m_designSize=size;
        emit changed(PCT_DESIGN_SIZE);
        setDurty(true);
    }
}

QSize QProject::getDesignSize()
{
    return m_projectInfo.m_designSize;
}

void QProject::setRunningSize(const QSize &size)
{
    if(m_projectInfo.m_runningSize!=size)
    {
        m_projectInfo.m_runningSize=size;
        emit changed(PCT_RUNNING_SIZE);
        setDurty(true);
    }
}

QSize QProject::getRunningSize()
{
    return m_projectInfo.m_runningSize;
}

void QProject::setNeedFrame(bool need)
{
    m_projectInfo.m_needFrame=need;
}

bool QProject::getNeedFrame()
{
    return m_projectInfo.m_needFrame;
}

void QProject::setCouldMax(bool could)
{
    m_projectInfo.m_couldMax=could;
}

bool QProject::getCouldMax()
{
    return m_projectInfo.m_couldMax;
}

void QProject::setCouldMin(bool could)
{
    m_projectInfo.m_couldMin=could;
}

bool QProject::getCouldMin()
{
    return m_projectInfo.m_couldMin;
}

QColor QProject::getBackColor()
{
    return m_projectInfo.m_backgroundColor;
}

void QProject::setBackColor(const QColor &color)
{
    m_projectInfo.m_backgroundColor=color;
}

QRuntimeData QProject::getRuntimeData(int index)
{
    if(index<0 || index>=m_projectInfo.m_runtimeDataList.size())
    {
        return QRuntimeData();
    }
    else
    {
        return *(m_projectInfo.m_runtimeDataList.at(index));
    }
}

int QProject::getRunningIndex(const QString &name)
{
    for(int i=0;i<m_projectInfo.m_runtimeDataList.size();i++)
    {
        if(m_projectInfo.m_runtimeDataList.at(i)->name()==name)
        {
            return i;
        }
    }
    return -1;
}

int QProject::getRuntimeDataCount()
{
    return m_projectInfo.m_runtimeDataList.size();
}

void QProject::setRuntimeData(int index, const QRuntimeData &info)
{
    if(index<0 || index>=m_projectInfo.m_runtimeDataList.size())
    {
        insertRuntimeData(index,info);
    }
    else
    {
        QRuntimeData *runtime=m_projectInfo.m_runtimeDataList.at(index);
        *runtime=info;
        emit changed(PCT_RUNNING_DATA_MODIFY,index);
        setDurty(true);
    }
}

void QProject::insertRuntimeData(int index, const QRuntimeData &info)
{
    if(index<0 || index>=m_projectInfo.m_runtimeDataList.size())
    {
        index=m_projectInfo.m_runtimeDataList.size();
    }
    QRuntimeData *runtime=new QRuntimeData();
    *runtime=info;
    m_projectInfo.m_runtimeDataList.insert(index,runtime);
    emit changed(PCT_RUNNING_DATA_ADD,index);
    setDurty(true);
}

void QProject::removeRuntimeData(int index)
{
    if(index<0 || index>=m_projectInfo.m_runtimeDataList.size())
    {
        return;
    }
    QRuntimeData *runtime=m_projectInfo.m_runtimeDataList.at(index);
    delete runtime;
    m_projectInfo.m_runtimeDataList.removeAt(index);
    emit changed(PCT_RUNNING_DATA_DEL,index);
    setDurty(true);
}

void QProject::moveRuntimeDataDown(int index)
{
    if(index<0 || index>=m_projectInfo.m_runtimeDataList.size())
    {
        return;
    }
    QRuntimeData *r=m_projectInfo.m_runtimeDataList.at(index);
    QRuntimeData *temp;
    for(int i=index+1;i<m_projectInfo.m_runtimeDataList.size();i++)
    {
        temp=m_projectInfo.m_runtimeDataList.at(i);
        if(r->category()==temp->category())
        {
            m_projectInfo.m_runtimeDataList.replace(index,temp);
            m_projectInfo.m_runtimeDataList.replace(i,r);
            setDurty(true);
            return;
        }
    }
}

void QProject::moveRuntimeDataUp(int index)
{
    if(index<0 || index>=m_projectInfo.m_runtimeDataList.size())
    {
        return;
    }
    QRuntimeData *r=m_projectInfo.m_runtimeDataList.at(index);
    QRuntimeData *temp;
    for(int i=index-1;i>=0;i--)
    {
        temp=m_projectInfo.m_runtimeDataList.at(i);
        if(r->category()==temp->category())
        {
            m_projectInfo.m_runtimeDataList.replace(index,temp);
            m_projectInfo.m_runtimeDataList.replace(i,r);
            setDurty(true);
            return;
        }
    }
}

tagPageInfo QProject::getPage(int index)
{
    if(index<0 || index>=m_projectInfo.m_pageList.size())
    {
        return tagPageInfo();
    }
    else
    {
        return *(m_projectInfo.m_pageList.at(index));
    }
}

tagPageInfo QProject::getPage(const QString &page)
{
    foreach(tagPageInfo *info,m_projectInfo.m_pageList)
    {
        if(info->m_name==page)
        {
            return *info;
        }
    }
    return tagPageInfo();
}

int QProject::getPageCount()
{
    return m_projectInfo.m_pageList.size();
}

void QProject::setPage(int index, const tagPageInfo &info)
{
    if(index<0 || index>=m_projectInfo.m_pageList.size())
    {
        return insertPage(index,info);
    }
    else
    {
        tagPageInfo* page=m_projectInfo.m_pageList.at(index);
        page->m_data=info.m_data;
        page->m_name=info.m_name;
        page->m_type=info.m_type;
        emit changed(PCT_PAGE_DATA_MODIFY,index);
        setDurty(true);
    }
}

void QProject::insertPage(int index, const tagPageInfo &info)
{
    if(index<0 || index>=m_projectInfo.m_pageList.size())
    {
        index=m_projectInfo.m_pageList.size();
    }
    if(info.m_name=="")
    {
        return;
    }
    for(int i=0;i<m_projectInfo.m_pageList.size();i++)
    {
        if(m_projectInfo.m_pageList.at(i)->m_name==info.m_name)
        {
            return;
        }
    }
    tagPageInfo *page=new tagPageInfo;
    page->m_data=info.m_data;
    page->m_name=info.m_name;
    page->m_type=info.m_type;
    if(page->m_data=="")
    {
        page->m_data="<widget class=\"QWidget\">\n"
                     "    <property name=\"pageName\">\n"
                     "        <string>page1</string>\n"
                     "    </property>\n"
                     "    <property name=\"size\">\n"
                     "        <size>\n"
                     "            <width>800</width>\n"
                     "            <height>600</height>\n"
                     "        </size>\n"
                     "    </property>\n"
                     "</widget>";
    }
    if(page->m_type=="")
    {
        page->m_type="page";
    }
    m_projectInfo.m_pageList.insert(index,page);
    if(m_projectInfo.m_strFirstPage=="")
    {
        m_projectInfo.m_strFirstPage=m_projectInfo.m_pageList.first()->m_name;
    }
    emit changed(PCT_PAGE_DATA_ADD,index);
    setDurty(true);
}

void QProject::removePage(int index)
{
    if(index<0 || index>=m_projectInfo.m_pageList.size())
    {
        return;
    }
    tagPageInfo *page=m_projectInfo.m_pageList.at(index);

    if(m_projectInfo.m_strFirstPage==page->m_name)
    {
        if(index==0)
        {
            if(m_projectInfo.m_pageList.size()==1)
            {
                m_projectInfo.m_strFirstPage="";
            }
        }
        else
        {
            m_projectInfo.m_strFirstPage=m_projectInfo.m_pageList.first()->m_name;
        }
    }
    emit changed(PCT_PAGE_DATA_DEL,index);
    m_projectInfo.m_pageList.removeAt(index);
    delete page;


    setDurty(true);
}

void QProject::removePage(const QString &name)
{
    foreach(tagPageInfo *info,m_projectInfo.m_pageList)
    {
        if(info->m_name==name)
        {
            emit changed(PCT_PAGE_DATA_DEL,m_projectInfo.m_pageList.indexOf(info));
            delete info;
            m_projectInfo.m_pageList.removeAll(info);
            setDurty(true);
            return;
        }
    }
}

tagResourctInfo QProject::getResource(const QString &name)
{
    tagResourctInfo *info=m_projectInfo.m_resourceList.value(name,NULL);
    return info==NULL?tagResourctInfo():(*info);
}

void QProject::insertResource(const QString &name,QObject *obj, const QString &key)
{
    QMap<QString,QString>  t=m_resourceUser.value(obj);
    QString n=t.value(key,"");
    if(n!="")
    {
        if(n==name)
        {
            return;
        }
        removeResource(obj,key);
    }
    if(name=="")
    {
        return;
    }
    int ti=m_resourceTimes.value(name,0);
    ti++;
    m_resourceTimes.value(name,ti);
    if(m_projectInfo.m_resourceList.value(name,NULL)==NULL)
    {
        tagResourctInfo *resource=new tagResourctInfo;
        resource->m_data=emit getResourceData(name);
        resource->m_name=name;
        ResourceMaker r;
        r.addData(name,resource->m_data);
        QByteArray array=r.save();
        uchar *buffer;
        if(array.size()>0)
        {
            uchar *uc=m_resourceData.value(name);
            if(uc!=NULL)
            {
                QResource::unregisterResource(uc,"/soft_res/");
                m_resourceData.remove(name);
                delete uc;
            }
            buffer=new uchar[array.size()];
            memcpy(buffer,array.data(),array.size());
            if(QResource::registerResource(buffer,"/soft_res/"))
            {
                m_resourceData.insert(name,buffer);
            }
            else
            {
                delete buffer;
            }

        }
        m_projectInfo.m_resourceList.insert(name,resource);

    }
    else
    {
        tagResourctInfo *resource=m_projectInfo.m_resourceList.value(name);
        resource->m_data=emit getResourceData(name);
    }
    setDurty(true);

    t=m_resourceUser.value(obj);
    t.insert(key,name);
    m_resourceUser.insert(obj,t);
}

void QProject::removeResource(QObject *obj, const QString &key)
{
    QMap<QString,QString>  t=m_resourceUser.value(obj);
    QString n=t.value(key,"");
    if(n!="")
    {
        t.remove(key);
        if(t.size()==0)
        {
            m_resourceUser.remove(obj);
        }
        tagResourctInfo *resource=m_projectInfo.m_resourceList.value(n);
        int ti=m_resourceTimes.value(n,0);
        ti--;
        if(ti<=0)
        {
            uchar *ch=m_resourceData.value(n,NULL);
            if(ch!=NULL)
            {
                QResource::unregisterResource(ch,"/soft_res/");
                delete [] ch;
                m_resourceData.remove(n);
            }
            delete resource;
            m_projectInfo.m_resourceList.remove(n);
            setDurty(true);
            m_resourceTimes.remove(n);
        }
        else
        {
            m_resourceTimes.insert(n,ti);
        }
    }
}

tagDriveInfo QProject::getDrive(const QString &name)
{
    foreach(tagDriveInfo *info,m_projectInfo.m_drives)
    {
        if(info->m_name==name)
        {
            return *info;
        }
    }
    return tagDriveInfo();
}

tagDriveInfo QProject::getDrive(int index)
{
    if(index<0 || index>=m_projectInfo.m_drives.size())
    {
        return tagDriveInfo();
    }
    else
    {
        return *(m_projectInfo.m_drives.at(index));
    }
}

int QProject::getDriveIndex(const QString &name)
{
    for(int i=0;i<m_projectInfo.m_drives.size();i++)
    {
        if(m_projectInfo.m_drives.at(i)->m_name==name)
        {
            return i;
        }
    }
    return -1;
}

int QProject::getDriveCount()
{
    return m_projectInfo.m_drives.size();
}

void QProject::insertDrive(int index, const tagDriveInfo &info)
{
    if(index<0 || index>m_projectInfo.m_drives.size())
    {
        index=m_projectInfo.m_drives.size();
    }
    tagDriveInfo *d=new tagDriveInfo();
    d->m_name=info.m_name;
    d->m_path=info.m_path;
    d->m_drive=info.m_drive;
    m_projectInfo.m_drives.insert(index,d);
    connect(d->m_drive,SIGNAL(attributeChanged()),this,SLOT(driveAttributeChanged()));
    setDurty(true);
}

void QProject::removeDrive(int index)
{
    if(index>=0 && index<m_projectInfo.m_drives.size())
    {
        m_projectInfo.m_drives.removeAt(index);
        setDurty(true);
    }
}

QString QProject::getProjectPath()
{
    return m_projectPath;
}

bool QProject::durty()
{
    return m_durty;
}

void QProject::setDurty(bool durty)
{
    m_durty=durty;
    emit durtyChanged();
}

void QProject::inserTempResource(const QString &name)
{
    if(m_tempResource.value(name)!=NULL)
    {
        return;
    }
    if(m_resourceData.keys().indexOf(name)>=0)
    {
        return;
    }
    ResourceMaker r;
    QByteArray array=emit getResourceData(name);
    r.addData(name,array);
    array=r.save();
    uchar *buffer;
    if(array.size()>0)
    {
        buffer=new uchar[array.size()];
        memcpy(buffer,array.data(),array.size());
        QResource::registerResource(buffer,"/soft_res/");
        m_tempResource.insert(name,buffer);
    }
}

void QProject::removeTempResource(const QString &name)
{
    uchar *buffer=m_tempResource.value(name,NULL);
    if(buffer!=NULL)
    {
        QResource::unregisterResource(buffer,"/soft_res/");
        m_tempResource.remove(name);
        delete [] buffer;
    }
}

QProject *QProject::project()
{
    if(m_project==NULL)
    {
        m_project=new QProject();
    }
    return m_project;
}

void QProject::releaseProject()
{
    if(m_project!=NULL)
    {
        delete m_project;
        m_project=NULL;
    }
}

void QProject::addDrivePlugin(const QString &path, QDrivePluginInterface *plugin)
{
    tagDrivePluginInfo info;
    info.m_drivePlugin=plugin;
    info.m_path=path;
    m_drives.insert(path,info);
}

QMap<QString,tagDrivePluginInfo> QProject::drivePlugins()
{
    return m_drives;
}

void QProject::driveAttributeChanged()
{
    setDurty(true);
}
